#!/Library/Frameworks/Python.framework/Versions/Current/bin/python

#from pybeetle.beetle import main

import sys, os
import optparse
import ConfigParser

from collections import defaultdict

from pybeetle import beetle
from pybeetle import __version__ as Version

from pybeetle.datamodels import KnownDM

defaults = defaultdict(str)
# these can be integers, strings,floats, tuples.
internal = {'check':'NaI5893',
    		'swin':250,
    		'indexsnr':5,
            'indexmin':3,
    		'spectralines':'hammer',
    		'fnorm':7042,
            'normalize':False,
            'plottype':'show',
            'figsize':(20, 12),
            'dpi':72,
            }
for k, v in internal.items(): defaults[k] = v

def check_listfile(option, opt, value, parser):
    if not os.path.exists(value):
        raise optparse.OptionValueError("%s does not seem to exist." % value)
    parser.values.listfile = os.path.realpath(value)

def check_datafile(option, opt, value, parser):
    if not os.path.exists(value):
        raise optparse.OptionValueError("%s does not seem to exist." % value)
    parser.values.datafile = os.path.realpath(value)

def check_datamodel(option, opt, value, parser):
    if KnownDM.count(value) == 0:
        print 'Using a generic data model (Unknown given)'
        parser.values.datamodel = "generic"
    else:
        parser.values.datamodel = value

def parse_initfile(option, opt, value, parser):
    """
    Parse a list [value] of init files, read them into defaults.
    Use class if internally defined defaults to flip init file values
    to correct format. The configparser object "c" appends the values
    of subsequent init files, overwriting previously defined sections/items 
    so giving precedance to latter init files in the list.
    """
    c = ConfigParser.SafeConfigParser()
    c.optionxform = lambda x: x
    values = value.split(',')

    for fooval in values:
        if not os.path.exists(fooval):
            values.remove(fooval)
            raise optparse.OptionValueError("%s does not seem to exist." % fooval)
        else:
            c.read(fooval)

    defaults['initfile'] = ",".join(values)

    for foo in c.sections():
        for k, v in c.items(foo):
            # converts section to known or default type
            if defaults[k].__class__ is not tuple:
                defaults[k] = defaults[k].__class__(v)
            else:
                defaults[k] = tuple(defaults[k][i].__class__(foo) for
                                    i, foo in enumerate(v.split(',')))

    parser.values.initfile = values


def main():
    #------------------ Populate our options, -h/--help is already there for you.
    usage = "usage: %prog [options]"
    epilog = "The program can accept either a data file containing a single spectrum (--data) or a text file with a  list of data files (--list). One of --data or --list is required."
    version = "%prog " + Version

    parser = optparse.OptionParser(usage=usage, version=version, epilog=epilog)
    parser.set_defaults(auto=True)
    parser.set_defaults(tweak=False)
    parser.set_defaults(plot=False)
    parser.add_option("-i", "--ini", dest="initfile", metavar="FILE(s),",
					action="callback", callback=parse_initfile, type="string",
					help="Optional user init file(s).")
    parser.add_option("-a", "--auto", dest="auto", action="store_true",
                    default=True,
                    help="Run auto type [default is: %default]")
    parser.add_option("-s", "--skip-auto", dest="auto", action="store_false",
                    help="Skip auto type")
    parser.add_option("-p", "--plot", dest="plot", action="store_true",
                    default=False,
                    help="Plot results [default is: %default]")
    parser.add_option("-t", "--tweak", dest="tweak", action="store_true",
                    default=False,
                    help="Tweak results by eye [default is: %default]")
    parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
                    default=False,
                    help="Trigger verbose stdout")

    #--------------------------------------------------------- group1: data files
    group1 = optparse.OptionGroup(parser, "Input as data file containing spectra", "")
    group1.add_option("-d", "--data", dest="datafile", metavar="FILE",
                    action="callback", callback=check_datafile, type="string",
                    help="File containing spectrum data.")
    group1.add_option("-m", "--model", dest="datamodel",
                    default="generic", metavar="generic",
                    action="callback", callback=check_datamodel, type="string",
                    help="Set data model for input spectra.\n" + \
                    "Known data models are: " + ", ".join(KnownDM) + \
                    " [default is: %default]")
    parser.add_option_group(group1)

    #-------------------------------------------------------- group 2: file lists
    group2 = optparse.OptionGroup(parser, "Input as file listing spectra and data models", "")
    group2.add_option("-l", "--list", dest="listfile", metavar="FILE",
                    action="callback", callback=check_listfile, type="string",
                    help="File containing list of spectra and models")
    parser.add_option_group(group2)

    #-------------------------------------------------------- group3: output file
    group3 = optparse.OptionGroup(parser, "Output Options", "")
    group3.add_option("-o", "--output", dest="outputfile", metavar="FILE",
                    default="./autoSpTresults.txt",
                    help="Output results file. [default: %default]")
    parser.add_option_group(group3)

    (options, args) = parser.parse_args()

    if not options.datafile and not options.listfile:
        parser.error("No valid input (file or list)")
        #parser.print_help()
        sys.exit()
    elif options.listfile is not None and options.datafile is not None:
        print 'Using the file list.'
        options.listfile = None
    elif options.datafile is not None:
        if not options.datamodel:
            print 'Using a generic data model (none given).'
            options.datamodel = 'generic'

    for k, v in options.__dict__.items():
        if not defaults.has_key(k):
            defaults[k] = v

    if options.verbose:
        da = 45
        print "%s\n%-25s\n%s" % ("-"*da, "Options given:", "-"*da)
        print "%-25s %s" % ('Auto type: ', defaults['auto'])
        print "%-25s %s" % ('Tweak fit: ', defaults['tweak'])
        print "%-25s %s" % ('Plot fit: ', defaults['plot'])
        print "%-25s %s" % ('Config File(s): ', defaults['initfile'])
        print "%-25s %s" % ('Input list: ', defaults['listfile'])
        print "%-25s %s" % ('Output file: ', defaults['outputfile'])
        print "%-25s %s" % ('Input Data: ', defaults['datafile'])
        print "%-25s %s" % ('Data model: ', defaults['datamodel'])
        print "%s\n%-25s\n%s" % ("-"*da, "Other defaults:", "-"*da)
        previous = ['auto', 'tweak', 'plot', 'initfile', 'listfile',
                    'outputfile', 'datafile', 'datamodel']
        for k, v in defaults.items():
            if k not in previous:
                print "%-25s %s" % (k, v)


    #----------------------------------------------------- run main driver script
    beetle.main(defaults)

if '__main__' == __name__:
    sys.exit(main())
